ASP.NET MVC Gegevens valideren
Validatieregels toevoegen in het model
Je kan de validatieregels zelf implementeren in de getters en setters van model- of eventueel de business logic layer. Je kan echter basisvalidatie met eenvoudige attributen in het model bepalen. Je leest er meer over in EF Business regels toevoegen met attributen. Als je attributen gebruikt wordt de feedback automatisch in de ModelState instantie opgeslagen, die je kan benaderen vanuit de View aarin de feedback uiteindelijk getoond moet worden.
Class-Level model validatie
met EF Code First en ASP.NET MVC
zie: http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3
ModelState
Wanneer het ASP.NET MVC Framework de actiemethode van een controller uitvoert kan je ook de gegevens die worden doorgegeven aan die controller actiemethode validereren. Foutmeldingen worden opgeslagen in een ModelState
object. Controller acties kunnen de ModelState
opvragen om na te gaan of de request geldig is en dienovereenkomstig te reageren. Als een veld niet correcht is ingevuld kan je de gebruiker laten terugkeren naar de pagina met invulformulier om de validatie fouten te corrigeren en een nieuwe request in te dienen.
Niet alleen het ASP.NET MVC Framework kan validatiefouten toevoegen aan ModelState
. Ontwikkelaars kunnen zelf ook validatiefouten toevoegen met de
ModelState.AddModelError (string key, string message)
methode.
[HttpPost] public ActionResult Insert(Models.PostalCodes postalCodes) { if (ModelState.IsValid) { ViewBag.Message = "Insert een postcode in de database"; db.PostalCodes.Add(postalCodes); db.SaveChanges(); } else { ModelState.AddModelError("Ongeldige gegevens", "Postcode en plaatsnaam moeten ingevuld zijn."); } return View("Selecting", db.PostalCodes); }
De validatie manueel uitvoeren
Je kan de validatie laten uitvoeren in de View maar ook in de Controller. Je kan dit op twee manieren doen, namelijk met ValidateModel
of met TryValidateModel
. Beiden komen uit de Controller basisklasse. De eerste methode genereert een uitzondering als er validatie fouten zijn opgetreden, terwijl de tweede methode alleen maar false retoruneert. Als je ModelState.IsValid controleert na de TryValidateModel methode te hebben opgeroepen, retourneert die false omdat er validatie fouten zijn opgetreden.
[HttpPost]
public ActionResult Insert(string UnitBaseCode, string UnitBaseName,
string UnitBaseDescription)
{
Models.Dal dal = new Models.Dal();
Models.UnitBase unitBase = new Models.UnitBase();
unitBase.Code = UnitBaseCode;
unitBase.Name = UnitBaseName;
unitBase.Description = UnitBaseDescription;
if (TryValidateModel(unitBase))
{
dal.DbSetUnitBase.Add(unitBase);
dal.SaveChanges();
}
return View("Inserting", dal.DbSetUnitBase);
}
Validatie foutmeldingen tonen
We weten nu al hoe we validatie foutmeldingen moeten maken, maar nog niet hoe we die aan de gebruiker moeten tonen. Dat gebeurt op een andere plaats in de MVC architectuur, namelijk in de view. We keren terug naar de view met de naam Selecting in de PostalCodes sectie.
We moeten nog een regel aan die markup toevoegen om te laten zien welke validatiemeldingen er zijn. We halen die uit direct uit de ModelState
, die kunnen bereiken via ViewData.ModelState
. en ViewData.ModelState ["Ongeldige gegevens"]
retourneert een object die een collectie bevat van fouten die van toepassing zijn op de eigenschap Ongeldige gegevens.
@if (ViewData.ModelState.Any()) { foreach (var error in ViewData.ModelState["Ongeldige gegevens"].Errors) { @error.ErrorMessage } }
ASP.NET MVC biedt een nog betere aanpak om alle van de foutmeldingen voor een bepaalde eigenschap te tonen: de Html.ValidationMessage (string ModelName)
helper. Met de Html.ValidationMessage() helper kan je de hele foreach
lus vervangen door een methodeaanroep om hetzelfde resultaat te bereiken:
@Html.ValidationMessageFor(model => model.PostalCode)
Je kan de Html.ValidationMessage()
voor elke eigenschap in je model oproepen. ASP.NET MVC zal nu al de validatie problemen die zich hebben voorgedaan tonen op dezelfde lijn als de velden waarop ze van toepassing zijn.
Daarnaast heeft ASP.NET MVC ook nog de Html.ValidationSummary()
helper. Met Html.ValidationSummary()
kan je alle validatie foutmeldingen in één keer op één plaats (bijvoorbeeld aan de bovenkant van de form) tonen, om de gebruiker een overzicht van fouten, die verbeterd moeten worden, te geven. Deze helper is ongelooflijk eenvoudig te gebruiken. Je hoeft slechts één keer Html.ValidationSummary() op te roepen.
@using (Html.BeginForm()) { @Html.ValidationSummary() @Html.LabelFor(model => model.PostalCode) @Html.EditorFor(model => model.PostalCode) @Html.ValidationMessageFor(model => model.PostalCode) }
Nu zullen eventuele foutmeldingen op plaatsente zien zijn: in de validatie-samenvatting (Html.ValidationSummary()
) en naast de waarde zelf (Html.ValidationMessage()
).
Je kan ook de foutmeldingen van Html.ValidationMessage() inlorten en korte, aangepaste foutmeldingen geven zoals een asterisk:
@Html.LabelFor(model => model.PostalCode) @Html.EditorFor(model => model.PostalCode) @Html.ValidationMessageFor(model => model.PostalCode, "*")
Debug feedback
Tijdens het onwikkelen in ASP.NET MVC kan je de volgende code in de Shared lay-out pagina plaatsen om te helpen debuggen:
<!-- During debugging I find it useful to put a table at the bottom of each of my pages to show all ModelState errors. Bron: http://stackoverflow.com/questions/1352948/how-to-get-all-errors-from-asp-net-mvc-modelstate --> <h3>Lijst van ModelState foutmeldingen</h3> <table class="model-state"> @foreach (var item in ViewContext.ViewData.ModelState) { if (item.Value.Errors.Any()) { <tr> <td><b>@item.Key</b></td> <td>@((item.Value == null || item.Value.Value == null) ? "<null>" : item.Value.Value.RawValue)</td> <td>@(string.Join("; ", item.Value.Errors.Select(x => x.ErrorMessage)))</td> </tr> } } </table>